/* test.cpp */

#include <iostream>
#include <iomanip>
#include <string>
#include <vector>
#include <algorithm>
#include <iterator>
#include <cstdlib>

#include "dodo_mm5.h"

using namespace std;
using namespace dodomet;
using namespace dodomet::mm5;

bool longer_than_12h(const Infolet& infolet)
{
	return infolet.xtime() > boost::posix_time::hours(12);
}

// This demo program takes several MM5 model file names as input parameter.
// Will print a list of the variable's information
// And tries to find and read a variable named "ALBD" in the files.
// And the records with a forecast time longer than 12 hours will not be processed.
// And at last, before any editing on that variable, writes them back as new to the files.
int main(int argc, char *argv[])
{
	if(argc == 1)
		return 0;

	Var_Pool pool;
	for(int i = 1; i < argc; ++i)
	{
		MM5_File mmfile(argv[i]);
		pool.add_mm5_file(mmfile);
	}

	// print each var's information
	for(Var_Pool::const_iterator iter = pool.begin(); iter != pool.end(); ++iter)
	{
		Var_Info info = *iter;

		// print name, size, etc.
		cout << setw(8) << info.name() << " : " 
			<< setw(25) << info.unit() << " : "
			<< setw(46) << info.description() 
			<< setw(8) << info.dim_size(0) 
			<< setw(8) << info.dim_size(1) 
			<< setw(8) << info.dim_size(2)
			<< setw(8) << info.field_size()
			<< setw(6) << info.ordering_name()
			<< endl;

		// print record information. 
		for(Var_Info::const_iterator record = info.begin(); record != info.end(); ++record)
		{
			cout << setw(30) << record->filename() << " "
				<< setw(20) << record->field_pos() << " "
				<< record->start_time() << " " 
				<< record->xtime() << " "<< endl;
		}
	}

	// testing finding a var named "ALBD". 
	// the size of this var is so small that we can print it on the screen.
	Var_Pool::iterator info_iter = pool.find_var_name("ALBD");
	if(info_iter == pool.end())
	{
		cout << "Cannot find var" << endl;
		return 0;
	}

	Var_Info info = *info_iter;
	info.remove_if(longer_than_12h);

	int total_size = info.total_size();
	
	int block_size = info.field_size();
	int block_num = info.ntime_steps();
	cout << "=== block_size: " << block_size << endl;
	cout << "=== block_num: " << block_num << endl;
	assert(total_size == block_size * block_num);

	assert(total_size > 0);

	vector<fortran_real> var(total_size, 0.0);
	// reading from file to container.
	info.fill_data(var.begin());
	copy(var.begin(), var.end(), ostream_iterator<fortran_real>(cout, " "));
	cout << endl;
	// You can edit the data as you will now.
	// ...
	// writing back to file.
	info.write_back(var.begin());
	
	return 0;
}

